<template>
  <global-layout>
    <contextmenu :itemList="menuItemList" :visible.sync="menuVisible" @select="onMenuSelect" />
    <a-tabs
      @contextmenu.native="e => onContextmenu(e)"
      v-if="multipage"
      :active-key="activePage"
      style="margin-top: -8px; margin-bottom: 8px"
      :hide-add="true"
      type="editable-card"
      @change="changePage"
      @edit="editPage">
      <a-tab-pane :id="page.fullPath" :key="page.fullPath" v-for="page in pageList">
        <span slot="tab" :pagekey="page.fullPath">{{page.meta.title}}</span>
      </a-tab-pane>
    </a-tabs>
    <transition name="page-toggle">
      <keep-alive v-if="multipage">
        <router-view />
      </keep-alive>
      <router-view v-else />
      <!-- <router-view /> -->
    </transition>
  </global-layout>
</template>

<script lang="ts">
import { Vue, Component, Watch } from 'vue-property-decorator'
import { State, Mutation, namespace } from 'vuex-class'
import GlobalLayout from './GlobalLayout.vue'
import Contextmenu from '@/components/src/menu/Contextmenu.vue'
const setting = namespace('setting')

@Component({
  components: {Contextmenu, GlobalLayout}
})
export default class MenuView extends Vue {
  @setting.State('multipage')
  public multipage!: boolean

  [index: string]: any
  public pageList: any[] = []
  public linkList: any[] = []
  public activePage: string = ''
  public menuVisible: boolean = false
  public menuItemList: any[] = [
    { key: '1', icon: 'arrow-left', text: '关闭左侧' },
    { key: '2', icon: 'arrow-right', text: '关闭右侧' },
    { key: '3', icon: 'close', text: '关闭其它' }
  ]

  public created() {
    this.pageList.push(this.$route)
    this.linkList.push(this.$route.fullPath)
    this.activePage = this.$route.fullPath
  }

  @Watch('$route')
  public onRouteChanged(newRoute: any, oldRoute: any) {
    this.activePage = newRoute.fullPath
    if (!this.multipage) {
      this.linkList = [newRoute.fullPath]
      this.pageList = [newRoute]
    } else if (this.linkList.indexOf(newRoute.fullPath) < 0) {
      this.linkList.push(newRoute.fullPath)
      this.pageList.push(newRoute)
    }
  }
  @Watch('activePage')
  public onActivePageChanged(key: string) {
    this.$router.push(key)
  }
  @Watch('multipage')
  public onMultipageChanged(newVal: any, oldVal: any) {
    if (!newVal) {
      this.linkList = [this.$route.fullPath]
      this.pageList = [this.$route]
    }
  }

  public changePage(key: string) {
    this.activePage = key
  }
  public editPage(key: any, action: any) {
    this[action](key)
  }
  public remove(key: string) {
    if (this.pageList.length === 1) {
      this.$message.warning('这是最后一页，不能再关闭了啦')
      return
    }
    this.pageList = this.pageList.filter((item: any) => item.fullPath !== key)
    let index: number = this.linkList.indexOf(key)
    this.linkList = this.linkList.filter((item: any) => item !== key)
    index = index >= this.linkList.length ? this.linkList.length - 1 : index
    this.activePage = this.linkList[index]
  }
  public onContextmenu(e: any) {
    const pagekey: any = this.getPageKey(e.target)
    if (pagekey !== null) {
      e.preventDefault()
      this.menuVisible = true
    }
  }
  /**
   * 由于ant-design-vue组件库的TabPane组件暂不支持自定义监听器，无法直接获取到右键target所在标签页的 pagekey 。故增加此方法用于
   * 查询右键target所在标签页的标识 pagekey ，以用于自定义右键菜单的事件处理。
   * 注：TabPane组件支持自定义监听器后可去除该方法并重构 ‘自定义右键菜单的事件处理’
   * @param target 查询开始目标
   * @param count 查询层级深度 （查找层级最多不超过3层，超过3层深度直接返回 null）
   * @returns {String | null}
   */
  public getPageKey(target: any, depth?: number) {
    depth = depth || 0
    if (depth > 2) {
      return null
    }
    let pageKey: any = target.getAttribute('pagekey')
    pageKey = pageKey || (target.previousElementSibling ? target.previousElementSibling.getAttribute('pagekey') : null)
    pageKey = pageKey || (target.firstElementChild ? this.getPageKey(target.firstElementChild, ++depth) : null)
    return pageKey
  }
  public onMenuSelect(key: any, target: any) {
    let pageKey: string = this.getPageKey(target)
    switch (key) {
      case '1':
        this.closeLeft(pageKey)
        break
      case '2':
        this.closeRight(pageKey)
        break
      case '3':
        this.closeOthers(pageKey)
        break
      default:
        break
    }
  }
  public closeOthers(pageKey: string) {
    let index: number = this.linkList.indexOf(pageKey)
    this.linkList = this.linkList.slice(index, index + 1)
    this.pageList = this.pageList.slice(index, index + 1)
    this.activePage = this.linkList[0]
  }
  public closeLeft(pageKey: string) {
    let index: number = this.linkList.indexOf(pageKey)
    this.linkList = this.linkList.slice(index)
    this.pageList = this.pageList.slice(index)
    if (this.linkList.indexOf(this.activePage) < 0) {
      this.activePage = this.linkList[0]
    }
  }
  public closeRight(pageKey: string) {
    let index: number = this.linkList.indexOf(pageKey)
    this.linkList = this.linkList.slice(0, index + 1)
    this.pageList = this.pageList.slice(0, index + 1)
    if (this.linkList.indexOf(+this.activePage < 0)) {
      this.activePage = this.linkList[this.linkList.length - 1]
    }
  }
}
</script>

<style scoped>

</style>
